import type { AstroIntegrationLogger } from "astro";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { generateSW, injectManifest, type StrategyName } from 'workbox-build'
import { build as esbuild } from 'esbuild'

export default async function injectCore(path: URL, pages: string[], logger: AstroIntegrationLogger) {
  const out = fileURLToPath(path);
  const SW_NAME = "service-worker.js";
  logger.info("Service Worker build start")
  // build website ts file to js
  await esbuild({
    entryPoints: ['src/service-worker/core/sw.ts'],
    outfile: 'src/service-worker/dist/sw.js',
    bundle: true,
    minify: true,
  })

  logger.info("Service Worker build esbuild success")

  // build service worker with workbox build
  const res = await generateSW({
    cleanupOutdatedCaches: true,
    clientsClaim: true,
    globDirectory: out,
    globPatterns: ["*.*"],
    swDest: join(out, SW_NAME),
    sourcemap: false,
    runtimeCaching: [
      // first ensure is pwa or website
      {
        urlPattern: () => window.matchMedia('(display-mode: standalone)').matches,
        handler: "NetworkFirst"
      },
      // route caching
      ...pages.map<{ urlPattern: RegExp; handler: StrategyName }>((page) => {
        return {
          urlPattern: new RegExp(`/${page}`),
          handler: "NetworkFirst"
        }
      })
    ]
  })

  if (res.warnings.length) {
    for (const warning of res.warnings) {
      logger.warn(warning)
    }
  }
  else {
    logger.info("Service Worker build success")
  }
}